﻿///////////////////////////////////////////////////////////////////////////////
// File:        Client.hpp
// Author:      671643387@qq.com
// Description:
///////////////////////////////////////////////////////////////////////////////


#ifndef PINGPONG_CLIENT_HPP_
#define PINGPONG_CLIENT_HPP_

#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif

#include <boost/shared_ptr.hpp>
#include <boost/function.hpp>
#include <boost/scoped_array.hpp>
#include <nio/net/EventHandler.hpp>
#include <nio/net/EventLoop.hpp>
#include <nio/net/Socket.hpp>

class Worker;

class Client : public nio::net::EventHandler
{
public:
    Client(nio::net::EventLoop& loop);
    virtual ~Client(void);

    bool open(std::string addr, int port, unsigned int bufSize, std::string message);

    virtual void handleInput(void);
    virtual void handleOutput(void);
    virtual void handleError(void);
    virtual void handleHeartbeat(void);

private:
    friend class Worker;

    enum State
    {
        READY,
        RUNNING,
        EXITING,
        EXIT
    };

    void close(void)
    {
        state_ = EXITING;
        closeFN_(id_);
    }

    void setId(int id)
    {
        id_ = id;
    }

    void setCloseFN(boost::function<void(int)> fn)
    {
        closeFN_ = fn;
    }

    nio::net::Socket& getSocket(void)
    {
        return sock_;
    }

private:
    int id_;
    State state_;
    nio::net::Socket sock_;
    nio::net::EventLoop& loop_;

    boost::scoped_array<char> buff_;
    unsigned int buffSize_;
    int buffLength_;

    boost::function<void(int)> closeFN_;
};

typedef boost::shared_ptr<Client> ClientPtr;

#endif //PINGPONG_CLIENT_HPP_
